package mebp.genetic.mutation;

import java.util.ArrayList;
import java.util.List;

import mebp.genetic.Population;

public class MutationRotation implements MutationStrategy {

	//final private double probability;
	List<MutationStrategy> strategies = new ArrayList<MutationStrategy>();
	List<MutationStrategy> bigGeneStrategies = new ArrayList<MutationStrategy>();
	List<MutationStrategy> smallGeneStrategies = new ArrayList<MutationStrategy>();
	
	public MutationRotation(double probability, Boolean keepBadMutations) {
		SimpleMutation sm = new SimpleMutation(probability, keepBadMutations);
		smallGeneStrategies.add(sm);
		BreakAndRelinkMutation br = new BreakAndRelinkMutation(probability, keepBadMutations);
		smallGeneStrategies.add(br);
		OptimizationMutation om = new OptimizationMutation(probability);
		smallGeneStrategies.add(om);
				
		strategies.add(sm);
		strategies.add(new RandomDoubleMutation(probability, keepBadMutations));
		strategies.add(br);
		strategies.add(new NeighborMutation(probability, keepBadMutations));
		strategies.add(new RandomTripleMutation(probability, keepBadMutations));
		strategies.add(om);
		
		bigGeneStrategies.add(sm);
		bigGeneStrategies.add(new RandomDoubleMutation(probability, keepBadMutations));
		bigGeneStrategies.add(br);
		RandomDoubleMutation rd = new RandomDoubleMutation(probability, keepBadMutations);
		rd.setMutationStrength(2);
		bigGeneStrategies.add(rd);
		bigGeneStrategies.add(new NeighborMutation(probability, keepBadMutations));
		bigGeneStrategies.add(new RandomTripleMutation(probability, keepBadMutations));
		bigGeneStrategies.add(om);
		RandomTripleMutation rt = new RandomTripleMutation(probability, keepBadMutations);
		rt.setMutationStrength(2);
		bigGeneStrategies.add(rt);
	}
	
	@Override
	public void mutate(Population population) {
		
		if (population.getBestResult().genom.length < 200) {
			int random = (int)Math.round(Math.random()*(smallGeneStrategies.size()-1)); 
			smallGeneStrategies.get(random).mutate(population);
		} else if (population.getBestResult().genom.length < 500) { 
			int random = (int)Math.round(Math.random()*(strategies.size()-1)); 
			strategies.get(random).mutate(population);
		} else {
			int random = (int)Math.round(Math.random()*(bigGeneStrategies.size()-1)); 
			bigGeneStrategies.get(random).mutate(population);
		}
	}
}
